package com.easylinkin.linkappapi.airconditioner.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.easylinkin.linkappapi.airconditioner.entity.AirDevice;
import com.easylinkin.linkappapi.airconditioner.entity.AirDeviceAttributeStatus;
import com.easylinkin.linkappapi.airconditioner.entity.AirMonitorQuery;
import com.easylinkin.linkappapi.airconditioner.entity.ext.AirConditionStatistic;
import com.easylinkin.linkappapi.airconditioner.entity.ext.DeviceTimerCount;
import com.easylinkin.linkappapi.airconditioner.mapper.AirMonitorMapper;
import com.easylinkin.linkappapi.airconditioner.service.AirMonitorService;
import com.easylinkin.linkappapi.airconditioner.util.AirPhysicalModelTypeConstant;
import com.easylinkin.linkappapi.security.context.LinkappUserContextProducer;
import com.easylinkin.linkappapi.security.entity.LinkappUser;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.ObjectUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
import org.thymeleaf.util.StringUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * class info :
 *
 * @author liuqihang
 * @date 2021/5/8 11:08
 */
@Service
@Slf4j
public class AirMonitorServiceImpl extends ServiceImpl<AirMonitorMapper, AirDevice> implements AirMonitorService {

    @Resource
    private LinkappUserContextProducer linkappUserContextProducer;

    private static final Logger LOGGER = LoggerFactory.getLogger(AirMonitorServiceImpl.class);


    public String getCurrentUser() throws Exception {
        LinkappUser current = linkappUserContextProducer.getCurrent();
        if(current == null || StringUtils.isEmpty(current.getTenantId())){
            throw new Exception("未获取到当前用户信息");
        }
        return current.getTenantId();
    }

    @Override
    public List<AirDevice> getAirDeviceListWs(Page page,AirMonitorQuery amq){
        Assert.notNull(amq.getFunctionIdentifier(), "功能识别码不能为空");
        amq.setAirConditionStatus(0);//默认查询全部

        if(org.springframework.util.StringUtils.isEmpty(amq.getTenantId())){
            try{
                String tenantId = getCurrentUser();
                amq.setTenantId(tenantId);
            }catch(Exception e){
                LOGGER.error(e.getMessage(), e);
            }
        }
        List<AirDevice> devices = baseMapper.getAirDevicePage(amq);
        if(devices == null ||devices.size()<=0){
            return null;
        }
        List<String> deviceCodeList = devices.stream().map(AirDevice::getCode).collect(Collectors.toList());
        List<DeviceTimerCount> deviceTimerCounts = baseMapper.checkTimerCountByDeviceCodeList(deviceCodeList);
        Map<String, List<DeviceTimerCount>> deviceTimerCountMap = null;
        if(!ObjectUtils.isEmpty(deviceTimerCounts)){
            deviceTimerCountMap = deviceTimerCounts.stream().collect(Collectors.groupingBy(DeviceTimerCount::getDeviceCode));
        }

        for (AirDevice childDevice : devices) {
            if(childDevice.getStatus().equals(0)){
                childDevice.setAirDeviceStatus(0);
            }
            if(ObjectUtils.isEmpty(deviceTimerCounts)){
                childDevice.setTimerFlag(0);
            }else {
                List<DeviceTimerCount> dtc = deviceTimerCountMap.get(childDevice.getCode());
                if(ObjectUtils.isEmpty(dtc)){
                    childDevice.setTimerFlag(0);
                }else {
                    DeviceTimerCount deviceTimerCount = dtc.get(0);
                    if(deviceTimerCount == null || deviceTimerCount.getNum() < 1){
                        childDevice.setTimerFlag(0);
                    }else {
                        childDevice.setTimerFlag(1);
                    }
                }
            }

            List<AirDeviceAttributeStatus> deviceAttributeList = childDevice.getDeviceAttributeStatusList();
            if(deviceAttributeList != null && deviceAttributeList.size() > 0){
                for (AirDeviceAttributeStatus adas:
                        deviceAttributeList) {
                    //airDeviceStatus;//0:正常，1:开机，2:故障，3:锁定，4:关机
                    String propCode = adas.getPropCode();
                    String propValue = adas.getPropValue();
                    if(AirPhysicalModelTypeConstant.air_switch.equals(propCode)){
                        if("1".equals(propValue)){
                            childDevice.setAirDeviceStatus(1);
                        }else  if("0".equals(propValue)){
                            childDevice.setAirDeviceStatus(4);
                        }
                    }
                    if(AirPhysicalModelTypeConstant.error_state.equals(propCode)){
                        if("1".equals(propValue)){
                            childDevice.setAirDeviceStatus(2);
                            break;//优先显示故障
                        }
                    }
                    if(AirPhysicalModelTypeConstant.lock_cmd.equals(propCode)){
                        if("15".equals(propValue)){
                            childDevice.setAirDeviceStatus(3);
                        }
                    }
                }
            }
            deviceAttributeList = getFormatDeviceAttributeStatusList(deviceAttributeList);
            childDevice.setDeviceAttributeStatusList(deviceAttributeList);
        }
        return devices;
    }

    @Override
    public IPage<AirDevice> getAirDevicePage(Page page, AirMonitorQuery amq) {
        log.info("请求参数：" + JSON.toJSONString(amq));
        Assert.notNull(amq.getFunctionIdentifier(), "功能识别码不能为空");
        if(amq.getAreaTreeVos() == null || amq.getAreaTreeVos().isEmpty()){
            log.info("空调监控设备类型查询：未获取到空间区域数据");
            return null;
        }

        if(amq.getAirConditionStatus() != null ){
            //查询正常
            if(amq.getAirConditionStatus().equals(1) ){
                amq.setStatus(0);
            }
            //查询开机
            else if(amq.getAirConditionStatus().equals(2) ){
                amq.setPropCode(AirPhysicalModelTypeConstant.air_switch);
                amq.setPropValue("1");
            }
            //查询故障
            else if(amq.getAirConditionStatus().equals(3) ){
                amq.setPropCode(AirPhysicalModelTypeConstant.error_state);
                amq.setPropValue("1");
            }
            //查询锁定：只要有锁定的信息就算入统计，这里的'0'表示解除锁定，需要在sql中进行逻辑处理
            else if(amq.getAirConditionStatus().equals(4) ){
                amq.setPropCode(AirPhysicalModelTypeConstant.lock_cmd);
                amq.setPropValue("0");
            }
            //查询定时
            else if(amq.getAirConditionStatus().equals(5) ){

            }
        }else {
            //默认查询全部
            amq.setAirConditionStatus(0);
        }
        try{
            String tenantId = getCurrentUser();
            amq.setTenantId(tenantId);
        }catch(Exception e){
            LOGGER.error(e.getMessage(), e);
        }

        IPage<AirDevice> result = baseMapper.getAirDevicePage(page, amq);
        List<AirDevice> devices = result.getRecords();
        if(ObjectUtils.isEmpty(devices)){
            return null;
        }
        List<String> deviceCodeList = devices.stream().map(AirDevice::getCode).collect(Collectors.toList());
        List<DeviceTimerCount> deviceTimerCounts = baseMapper.checkTimerCountByDeviceCodeList(deviceCodeList);
        Map<String, List<DeviceTimerCount>> deviceTimerCountMap = null;
        if(!ObjectUtils.isEmpty(deviceTimerCounts)){
            deviceTimerCountMap = deviceTimerCounts.stream().collect(Collectors.groupingBy(DeviceTimerCount::getDeviceCode));
        }

        for (AirDevice childDevice : devices) {
            if(childDevice.getStatus().equals(0)){
                childDevice.setAirDeviceStatus(0);
            }

            if(ObjectUtils.isEmpty(deviceTimerCounts)){
                childDevice.setTimerFlag(0);
            }else {
                List<DeviceTimerCount> dtc = deviceTimerCountMap.get(childDevice.getCode());
                if(ObjectUtils.isEmpty(dtc)){
                    childDevice.setTimerFlag(0);
                }else {
                    DeviceTimerCount deviceTimerCount = dtc.get(0);
                    if(deviceTimerCount == null || deviceTimerCount.getNum() < 1){
                        childDevice.setTimerFlag(0);
                    }else {
                        childDevice.setTimerFlag(1);
                    }
                }
            }

            List<AirDeviceAttributeStatus> deviceAttributeList = childDevice.getDeviceAttributeStatusList();
            if(deviceAttributeList != null && deviceAttributeList.size() > 0){
                for (AirDeviceAttributeStatus adas:
                    deviceAttributeList) {
                    //airDeviceStatus;//0:正常，1:开机，2:故障，3:锁定，4:关机
                    String propCode = adas.getPropCode();
                    String propValue = adas.getPropValue();
                    if(AirPhysicalModelTypeConstant.air_switch.equals(propCode)){
                        if("1".equals(propValue)){
                            childDevice.setAirDeviceStatus(1);
                        }else  if("0".equals(propValue)){
                            childDevice.setAirDeviceStatus(4);
                        }
                    }
                    if(AirPhysicalModelTypeConstant.error_state.equals(propCode)){
                        if("1".equals(propValue)){
                            childDevice.setAirDeviceStatus(2);
                            break;//优先显示故障
                        }
                    }
                    if(AirPhysicalModelTypeConstant.lock_cmd.equals(propCode)){
                        if("15".equals(propValue)){
                            childDevice.setAirDeviceStatus(3);
                        }
                    }
                }
            }
            deviceAttributeList = getFormatDeviceAttributeStatusList(deviceAttributeList);
            childDevice.setDeviceAttributeStatusList(deviceAttributeList);
        }
        return result;
    }

    private AirMonitorQuery getAirMonitorQueryInstance(AirMonitorQuery sourceAmq){
        AirMonitorQuery result = new AirMonitorQuery();
        try{
            if(sourceAmq.getAirConditionStatus() == null){
                result.setAirConditionStatus(0);
            }
            if(!org.springframework.util.StringUtils.isEmpty(sourceAmq.getTenantId())){
                result.setTenantId(sourceAmq.getTenantId());
            }else{
                String tenantId = getCurrentUser();
                result.setTenantId(tenantId);
            }

            result.setFunctionIdentifier(sourceAmq.getFunctionIdentifier());
            result.setAreaTreeVos(sourceAmq.getAreaTreeVos());

        }catch(Exception e){
            LOGGER.error(e.getMessage(), e);
        }

        return result;
    }

    @Override
    public AirConditionStatistic getAirConditionStatistic(AirMonitorQuery amq) {
        Assert.notNull(amq.getFunctionIdentifier(), "page 不能为空");
        AirConditionStatistic acs = new AirConditionStatistic();
        if(amq.getAreaTreeVos() == null || amq.getAreaTreeVos().isEmpty()){
            log.info("空调监控设备类型查询：未获取到空间区域数据");
            acs.setAllNum(0);
            acs.setNormalNum(0);
            acs.setOpenNum(0);
            acs.setErrorNum(0);
            acs.setLockNum(0);
            acs.setTimerNum(0);
            return acs;
        }
        AirMonitorQuery amq0 = getAirMonitorQueryInstance(amq);
        //查询全部
        Integer allNum = baseMapper.getAirConditionStatistic(amq0);
        //查询正常
        amq0.setStatus(0);
        Integer normalNum = baseMapper.getAirConditionStatistic(amq0);

        //查询开机
        AirMonitorQuery amq2 = getAirMonitorQueryInstance(amq);
        amq2.setPropCode("air_switch");
        amq2.setPropValue("1");
        amq2.setPropCode(AirPhysicalModelTypeConstant.air_switch);
        amq2.setPropValue("1");
        Integer openNum = baseMapper.getAirConditionStatistic(amq2);

        //查询故障
        AirMonitorQuery amq3 = getAirMonitorQueryInstance(amq);
        amq3.setPropCode(AirPhysicalModelTypeConstant.error_state);
        amq3.setPropValue("1");
        Integer errorNum = baseMapper.getAirConditionStatistic(amq3);

        //查询锁定：只要有锁定的信息就算入统计，这里的'0'表示解除锁定，需要在sql中进行逻辑处理
        AirMonitorQuery amq4 = getAirMonitorQueryInstance(amq);
        amq4.setPropCode(AirPhysicalModelTypeConstant.lock_cmd);
        amq4.setPropValue("0");
        Integer lockNum = baseMapper.getAirConditionStatistic(amq4);

        //查询定时
        AirMonitorQuery amq5 = getAirMonitorQueryInstance(amq);
        amq5.setAirConditionStatus(5);
        Integer timerNum = baseMapper.getAirConditionStatistic(amq5);

        acs.setAllNum(allNum);
        acs.setNormalNum(normalNum);
        acs.setOpenNum(openNum);
        acs.setErrorNum(errorNum);
        acs.setLockNum(lockNum);
        acs.setTimerNum(timerNum);
        return acs;
    }

    public List<AirDeviceAttributeStatus> getFormatDeviceAttributeStatusList(List<AirDeviceAttributeStatus> deviceAttributeStatusList) {
        List<String> complexTypesList = Arrays.asList(AirPhysicalModelTypeConstant.air_switch,
                AirPhysicalModelTypeConstant.air_mode,
                AirPhysicalModelTypeConstant.air_wind_speed,
                AirPhysicalModelTypeConstant.error_state,
                AirPhysicalModelTypeConstant.lock_cmd,
                AirPhysicalModelTypeConstant.air_temperature);
        List<AirDeviceAttributeStatus> resultList = new ArrayList<AirDeviceAttributeStatus>();

        List<AirDeviceAttributeStatus> topAttributes = deviceAttributeStatusList.stream().filter(e -> ObjectUtils.isEmpty(e.getParentPropCode())).collect(Collectors.toList());
        for (AirDeviceAttributeStatus topAttribute : topAttributes) {
            if (complexTypesList.contains(topAttribute.getPropCode())) {
                resultList.add(topAttribute);
            }
        }
        resultList.sort((a, b) -> {
            if (a.getSortNo() != null && b.getSortNo() != null && !a.getSortNo().equals(b.getSortNo())) {
                return a.getSortNo() > b.getSortNo() ? 1 : -1;
            }
            return 0;
        });
        return resultList;
    }


}
